/* @(#)FseDocument.java
** 
** Copyright (C) 2012 by Steven D. Stamps
**
**             Trademarks & Copyrights
** Flywheel Management Science(TM), Flywheel Management Model(TM),
** Flywheel Story Editor(TM) and FlywheelMS(TM) are exclusive trademarks
** of Steven D. Stamps and may only be used freely for the purpose of
** identifying the unforked version of this software.  Subsequent forks
** may not use these trademarks.  All other rights are reserved.
**
** DecKanGL (Decorated Kanban Glyph Language) and TribKn (Tribal Knowledge)
** are also exclusive trademarks of Steven D. Stamps.  These may be used
** freely within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** gConGUI (game Controller Graphical User Interface) is an exclusive
** trademark of Steven D. Stamps.  This trademark may be used freely
** within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** Trademark information is available at
** <http://www.flywheelms.com/trademarks>
**
** Flywheel Management Science(TM) is a copyrighted body of management
** metaphors, governance processes, and leadership techniques that is
** owned by Steven D. Stamps.  These copyrighted materials may be freely
** used, without alteration, by the community (users and developers)
** surrounding this GPL3-licensed software.  Additional copyright
** information is available at <http://www.flywheelms.org/copyrights>
**
**              GPL3 Software License
** This program is free software: you can use it, redistribute it and/or
** modify it under the terms of the GNU General Public License, version 3,
** as published by the Free Software Foundation. This program is distributed
** in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
** even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
** PURPOSE.  See the GNU General Public License for more details. You should
** have received a copy of the GNU General Public License, in a file named
** COPYING, along with this program.  If you cannot find your copy, see
** <http://www.gnu.org/licenses/gpl-3.0.html>.
*/

package com.flywheelms.library.fse.model;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.UUID;

import org.json.JSONException;
import org.json.JSONObject;

import com.flywheelms.library.deckangl.glyph.DecKanGlGlyph;
import com.flywheelms.library.fca.FlywheelCommunityAuthentication;
import com.flywheelms.library.fmm.enumerator.FmmLockStatus;
import com.flywheelms.library.fmm.node.NodeId;
import com.flywheelms.library.fmm.node.impl.enumerator.FmmNodeDictionary;
import com.flywheelms.library.fmm.node.impl.nodefrag.FmmNodeFragImpl;
import com.flywheelms.library.fmm.node.impl.nodefrag.NodeFragAuditBlock;
import com.flywheelms.library.fmm.node.impl.nodefrag.NodeFragGovernance;
import com.flywheelms.library.fmm.node.interfaces.horizontal.FmmNode;
import com.flywheelms.library.fmm.node.interfaces.horizontal.FmmNodeAudit;
import com.flywheelms.library.fmm.serialization.FmmSerialization;
import com.flywheelms.library.fmm.serialization.FseDocumentSerialization;
import com.flywheelms.library.fse.FseDocumentSectionType;
import com.flywheelms.library.fse.enumerator.FseContentModificationState;
import com.flywheelms.library.fse.enumerator.FseLockModificationState;
import com.flywheelms.library.fse.enumerator.FseNotesTemplate;
import com.flywheelms.library.fse.enumerator.FseStoryTemplate;
import com.flywheelms.library.fse.enumerator.FseStyleModificationState;
import com.flywheelms.library.fse.views.FseDocumentSectionAuditView;
import com.flywheelms.library.fse.views.FseDocumentSectionHistoryView;
import com.flywheelms.library.fse.views.FseDocumentSectionNotesView;
import com.flywheelms.library.fse.views.FseDocumentSectionStoryView;
import com.flywheelms.library.fse.views.FseDocumentSectionTribKnView;
import com.flywheelms.library.util.JsonHelper;

public class FseDocument extends FmmNodeFragImpl
		implements FmmSerialization, FmmNodeAudit, Cloneable {
	
	private Date dbTimestamp = new Date();
	private String serializedDocument;
	private String serializationFormatVersion = "0.1";
	/*
	 * Should contain:
	 * - FmmNodeInfo
	 * - governance info
	 * - document notes
	 * - document history
	 */
//	private NodeFragAuditBlock auditBlock;
	private boolean forPublication = false;  // publication requires a Headline and TribKn
	private int documentMarginLeft = 10;
	private FseDocumentSectionType initialDocumentSectionType;
	private HashMap<FseDocumentSectionType, FseDocumentSection> documentSections = new HashMap<FseDocumentSectionType, FseDocumentSection>();

	/*
	 *  TODO    need to add a constructor using the FmmNodeInfo argument
	 *  		the template for that node type will be used to
	 *  		initialize the paragraphList  -  SDS
	 */
	
	// de-serialize an existing document
	public FseDocument(String aSerializedDocument) {
		this(aSerializedDocument, aSerializedDocument);
	}
	
	// de-serialize an existing document
	public FseDocument(String aSerializedDocument, String aSerializedBaselineDocuument) {
		super(NodeId.rehydrate(FseDocument.class, getDocumentIdFromSerializedDocument(aSerializedDocument)), getParentIdFromSerializedDocument(aSerializedBaselineDocuument));
		this.serializedDocument = aSerializedBaselineDocuument;
		this.documentSections.put(FseDocumentSectionType.TRIBKN, new FseDocumentSectionTribKn());
		this.documentSections.put(FseDocumentSectionType.AUDIT, new FseDocumentSectionAudit());
		this.documentSections.put(FseDocumentSectionType.HISTORY, new FseDocumentSectionHistory());
		this.documentSections.put(FseDocumentSectionType.NOTES, new FseDocumentSectionNotes());
		this.documentSections.put(FseDocumentSectionType.STORY, new FseDocumentSectionStory());
		inflateFromSerialization(aSerializedDocument);
	}

	// create a new document, for publication, that has never been serialized/persisted
	public FseDocument(
			String aParentNodeIdString,
			String aHeadline,
			DecKanGlGlyph aDecKanGlGlyph,
			NodeFragGovernance aNodeFragGovernance,
			FseStoryTemplate anFseStoryTemplate,
			FseNotesTemplate anFseNotesTemplate ) {
		super(NodeId.rehydrate(FseDocument.class, generateDocumentId()), aParentNodeIdString);
		aNodeFragGovernance.getNodeId().replaceTemporaryNodeId(getNodeIdString());
		this.forPublication = true;
		this.initialDocumentSectionType = FseDocumentSectionType.NOTES;
		this.documentSections.put(FseDocumentSectionType.TRIBKN, new FseDocumentSectionTribKn(aHeadline, aDecKanGlGlyph, aNodeFragGovernance));
		this.documentSections.put(FseDocumentSectionType.AUDIT, new FseDocumentSectionAudit(new NodeFragAuditBlock(getDocumentId()), new FseCommunityMemberParticipationSummary()));
		this.documentSections.put(FseDocumentSectionType.HISTORY, new FseDocumentSectionHistory());
		this.documentSections.put(FseDocumentSectionType.NOTES, new FseDocumentSectionNotes());
		this.documentSections.put(FseDocumentSectionType.STORY, new FseDocumentSectionStory());
		newStorySection(anFseStoryTemplate);
		newNotesSection(anFseNotesTemplate);
		this.serializedDocument = getSerialized();  // template is our baseline
	}
	
	// Used to create an FseDocument from an FseDocumentView, without coupling
	public FseDocument(String aDocumentId, String aParentNodeIdString, int aDocumentMarginLeft) {
		super(NodeId.rehydrate(FseDocument.class, aDocumentId), aParentNodeIdString);
		this.serializedDocument = "";  // force a "dirty" condition on first comparison with document view
		this.documentMarginLeft = aDocumentMarginLeft;
	}
	
	// create a new FseDocument for a parent
    public FseDocument(String aParentNodeIdString, boolean isForPublishing) {
		super(NodeId.rehydrate(FseDocument.class, generateDocumentId()), aParentNodeIdString);
		this.forPublication = isForPublishing;
		this.initialDocumentSectionType = FseDocumentSectionType.NOTES;
		Class<? extends FmmNode> theParentClass = FmmNodeDictionary.getEntryForNodeIdString(aParentNodeIdString).getNodeClass();
		this.documentSections.put(FseDocumentSectionType.AUDIT, new FseDocumentSectionAudit(new NodeFragAuditBlock(getDocumentId()), new FseCommunityMemberParticipationSummary()));
		this.documentSections.put(FseDocumentSectionType.HISTORY, new FseDocumentSectionHistory());
		this.documentSections.put(FseDocumentSectionType.NOTES, new FseDocumentSectionNotes());
		this.documentSections.put(FseDocumentSectionType.STORY, new FseDocumentSectionStory());
		newStorySection(FseStoryTemplate.getTemplateForClass(theParentClass));
		newNotesSection(FseNotesTemplate.getTemplateForClass(theParentClass));
		this.serializedDocument = getSerialized();  // template is our baseline
	}

	@Override
	public FseDocument clone() {
    	FseDocument theDocumentClone = new FseDocument(this.getSerialized());
        return theDocumentClone;
    }
	
	public static String generateDocumentId() {
		StringBuilder theStringBuilder = new StringBuilder(FmmNodeDictionary.getEntryForClass(FseDocument.class).getNodeTypeCode() + "-");
		theStringBuilder.append(UUID.randomUUID());
		return theStringBuilder.toString();
	}

	public String getDocumentId() {
		return getNodeIdString();
	}

	public FseDocumentSectionType getInitialDocumentSectionType() {
		return this.initialDocumentSectionType;
	}

	public void setInitialDocumentSectionType(
			FseDocumentSectionType initialDocumentSectionType) {
		this.initialDocumentSectionType = initialDocumentSectionType;
	}

	public FseDocumentSectionTribKn getDocumentSectionTribKn() {
		return (FseDocumentSectionTribKn) this.documentSections.get(FseDocumentSectionType.TRIBKN);
	}

	public FseDocumentSectionAudit getDocumentSectionAudit() {
		return (FseDocumentSectionAudit) this.documentSections.get(FseDocumentSectionType.AUDIT);
	}

	public FseDocumentSectionHistory getDocumentSectionHistory() {
		return (FseDocumentSectionHistory) this.documentSections.get(FseDocumentSectionType.HISTORY);
	}

	public FseDocumentSectionStory getDocumentSectionStory() {
		return (FseDocumentSectionStory) this.documentSections.get(FseDocumentSectionType.STORY);
	}
	
	public FseDocumentSectionNotes getDocumentSectionNotes() {
		return (FseDocumentSectionNotes) this.documentSections.get(FseDocumentSectionType.NOTES);
	}

	private void newStorySection(FseStoryTemplate anFseStoryTemplate) {
		getDocumentSectionStory().setParagraphList(new LinkedList<FseParagraph>());
		for(FseTemplateParagraph theFseTemplateParagraph : anFseStoryTemplate.getFseTemplateParagraphArray()) {
			getDocumentSectionStory().getParagraphList().add(new FseParagraph(theFseTemplateParagraph));
		}
		getDocumentSectionStory().setInitialParagraphFocusIndex(anFseStoryTemplate.getInitialParagraphFocusIndex());
		getDocumentSectionStory().setInitialParagraphFocusCursorPosition(anFseStoryTemplate.getInitialParagraphFocusCursorPosition());
		getDocumentSectionStory().setLockModificationState(FseLockModificationState.UNCHANGED);
		getDocumentSectionStory().setContentModificationState(FseContentModificationState.NEW);
		getDocumentSectionStory().setStyleModificationState(FseStyleModificationState.UNCHANGED);
	}

	private void newNotesSection(FseNotesTemplate anFseNotesTemplate) {
		getDocumentSectionNotes().setParagraphList(new LinkedList<FseParagraph>());
		for(FseTemplateParagraph theFseTemplateParagraph : anFseNotesTemplate.getFseTemplateParagraphArray()) {
			getDocumentSectionNotes().getParagraphList().add(new FseParagraph(theFseTemplateParagraph));
		}
		getDocumentSectionNotes().setInitialParagraphFocusIndex(anFseNotesTemplate.getInitialParagraphFocusIndex());
		getDocumentSectionNotes().setInitialParagraphFocusCursorPosition(anFseNotesTemplate.getInitialParagraphFocusCursorPosition());
		getDocumentSectionNotes().setLockModificationState(FseLockModificationState.UNCHANGED);
		getDocumentSectionNotes().setContentModificationState(FseContentModificationState.NEW);
		getDocumentSectionNotes().setStyleModificationState(FseStyleModificationState.UNCHANGED);
	}
	
	private static String getDocumentIdFromSerializedDocument(String aSerializedDocument) {
		try {
			JSONObject theJsonObject = new JSONObject(aSerializedDocument);
			return theJsonObject.getString(FseDocumentSerialization.key__DOCUMENT_ID);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";	
	}
	
	private static String getParentIdFromSerializedDocument(String aSerializedDocument) {
		try {
			JSONObject theJsonObject = new JSONObject(aSerializedDocument);
			return theJsonObject.getString(FseDocumentSerialization.key__PARENT_ID);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";	
	}

	private void inflateFromSerialization(String aSerializedDocument) {
		try {
			JSONObject theJsonObject = new JSONObject(aSerializedDocument);
			this.dbTimestamp = JsonHelper.getDate(theJsonObject, FseDocumentSerialization.key__PARENT_ID);
			this.serializationFormatVersion = theJsonObject.getString(FseDocumentSerialization.key__SERIALIZATION_FORMAT_VERSION);
			this.forPublication = theJsonObject.getBoolean(FseDocumentSerialization.key__FOR_PUBLICATION);
			this.documentMarginLeft = theJsonObject.getInt(FseDocumentSerialization.key__DOCUMENT_MARGIN__LEFT);
			this.initialDocumentSectionType = FseDocumentSectionType.getTypeForString(theJsonObject.getString(FseDocumentSerialization.key__DOCUMENT_INITIAL_SECTION_TAB));
			if(this.forPublication) {
				this.documentSections.put(
						FseDocumentSectionType.TRIBKN,
						new FseDocumentSectionTribKn(theJsonObject.getJSONObject(FseDocumentSerialization.key__DOCUMENT_SECTION__TRIBKN)) );
			}
			this.documentSections.put(
					FseDocumentSectionType.AUDIT,
					new FseDocumentSectionAudit(theJsonObject.getJSONObject(FseDocumentSerialization.key__DOCUMENT_SECTION__AUDIT)) );
			this.documentSections.put(
					FseDocumentSectionType.HISTORY,
					new FseDocumentSectionHistory(theJsonObject.getJSONObject(FseDocumentSerialization.key__DOCUMENT_SECTION__HISTORY)) );
			this.documentSections.put(
					FseDocumentSectionType.NOTES,
					new FseDocumentSectionNotes(theJsonObject.getJSONObject(FseDocumentSerialization.key__DOCUMENT_SECTION__NOTES)) );
			this.documentSections.put(
					FseDocumentSectionType.STORY,
					new FseDocumentSectionStory(theJsonObject.getJSONObject(FseDocumentSerialization.key__DOCUMENT_SECTION__STORY)) );
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public boolean forPublication() {
		return this.forPublication;
	}
	
	public void setForPublication(boolean aBoolean) {
		this.forPublication = aBoolean;
	}

	public String getHeadline() {
		return getDocumentSectionTribKn().getHeadline();
	}
	
	public int getDocumentMarginLeft() {
		return this.documentMarginLeft;
	}

	/**
	 * at this point, FseDocument is only created from a serialized source
	 * or from a template.  FseDocument is currently (functionally) immutable.
	 */
	@Override
	public String getSerialized() {
		if(this.serializedDocument == null) {  // null if this is a new document from template
			this.serializedDocument = getJsonObject().toString();
		}
		return this.serializedDocument;
	}
	
	@Override
	public JSONObject getJsonObject() {
		JSONObject theJsonObject = new JSONObject();
		try {
			theJsonObject.put(FseDocumentSerialization.key__SERIALIZATION_FORMAT_VERSION, FseDocumentSerialization.SERIALIZATION_FORMAT_VERSION);
			theJsonObject.put(FseDocumentSerialization.key__DOCUMENT_ID, getNodeIdString());
			theJsonObject.put(FseDocumentSerialization.key__PARENT_ID, getParentNodeIdString());
			theJsonObject.put(FseDocumentSerialization.key__FOR_PUBLICATION, this.forPublication);
			JsonHelper.putDate(theJsonObject, FseDocumentSerialization.key__DB_TIMESTAMP, this.dbTimestamp);
			theJsonObject.put(FseDocumentSerialization.key__DOCUMENT_MARGIN__LEFT, this.documentMarginLeft);
			theJsonObject.put(FseDocumentSerialization.key__DOCUMENT_INITIAL_SECTION_TAB, this.initialDocumentSectionType.toString());  // TODO - should only be updated if there are other substantive changes  SDS
			if(this.forPublication) {
				theJsonObject.put(FseDocumentSerialization.key__DOCUMENT_SECTION__TRIBKN, ((FseDocumentSectionTribKn) this.documentSections.get(FseDocumentSectionType.TRIBKN)).getJsonObject());
			}
			theJsonObject.put(FseDocumentSerialization.key__DOCUMENT_SECTION__AUDIT, ((FseDocumentSectionAudit) this.documentSections.get(FseDocumentSectionType.AUDIT)).getJsonObject());
			theJsonObject.put(FseDocumentSerialization.key__DOCUMENT_SECTION__HISTORY, ((FseDocumentSectionHistory) this.documentSections.get(FseDocumentSectionType.HISTORY)).getJsonObject());
			theJsonObject.put(FseDocumentSerialization.key__DOCUMENT_SECTION__STORY, ((FseDocumentSectionParagraphEditorContent) this.documentSections.get(FseDocumentSectionType.STORY)).getJsonObject());
			theJsonObject.put(FseDocumentSerialization.key__DOCUMENT_SECTION__NOTES, ((FseDocumentSectionParagraphEditorContent) this.documentSections.get(FseDocumentSectionType.NOTES)).getJsonObject());
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return theJsonObject;
	}
	
	public LinkedList<FseParagraph> getParagraphList(FseDocumentSectionType aSectionType) {
		LinkedList<FseParagraph> theParagraphList;
		switch (aSectionType) {
		case STORY:
			theParagraphList = getDocumentSectionStory().getParagraphList();
			break;
		case NOTES:
			theParagraphList = getDocumentSectionNotes().getParagraphList();
			break;
		default:
			theParagraphList = null;
		}
		return theParagraphList;
	}
	
	public int getInitialParagraphFocusIndex(FseDocumentSectionType aSectionType) {
		int theFocusIndex;
		switch (aSectionType) {
		case STORY:
			theFocusIndex = getDocumentSectionStory().getInitialParagraphFocusIndex();
			break;
		case NOTES:
			theFocusIndex = getDocumentSectionNotes().getInitialParagraphFocusIndex();
			break;
		default:
			theFocusIndex = 0;
		}
		return theFocusIndex;
	}
	
	public FseParagraph getInitialParagraphFocus(FseDocumentSectionType aSectionType) {
		FseParagraph theParagraph;
		switch (aSectionType) {
		case STORY:
			theParagraph = getDocumentSectionStory().getParagraphList().get(getInitialParagraphFocusIndex(aSectionType));
			break;
		case NOTES:
			theParagraph = getDocumentSectionNotes().getParagraphList().get(getInitialParagraphFocusIndex(aSectionType));
			break;
		default:
			theParagraph = null;
		}
		return theParagraph;
	}
	
	public int getInitialParagraphFocusCursorPosition(FseDocumentSectionType aSectionType) {
		int theCursorPosition;
		switch (aSectionType) {
		case STORY:
			theCursorPosition = getDocumentSectionStory().getInitialParagraphFocusCursorPosition();
			break;
		case NOTES:
			theCursorPosition = getDocumentSectionNotes().getInitialParagraphFocusCursorPosition();
			break;
		default:
			theCursorPosition = 0;
		}
		return theCursorPosition;
	}

	public void setDocumentSectionTribKn(FseDocumentSectionTribKnView aDocumentSectionTribKnView) {
		FseDocumentSectionTribKn theDocumentSectionTribKn = aDocumentSectionTribKnView.getDocumentSectionClone();
		this.documentSections.put(FseDocumentSectionType.TRIBKN, theDocumentSectionTribKn);
	}

	public void setDocumentSectionAudit(FseDocumentSectionAuditView aDocumentSectionAuditView) {
		FseDocumentSectionAudit theDocumentSectionAudit = aDocumentSectionAuditView.getDocumentSectionClone();
		this.documentSections.put(FseDocumentSectionType.AUDIT, theDocumentSectionAudit);
	}

	public void setDocumentSectionHistory(FseDocumentSectionHistoryView aDocumentSectionHistoryView) {
		this.documentSections.put(FseDocumentSectionType.HISTORY, aDocumentSectionHistoryView.getDocumentSectionClone());
	}

	public void setDocumentSectionStory(FseDocumentSectionStoryView aDocumentSectionStoryView) {
		this.documentSections.put(FseDocumentSectionType.STORY, aDocumentSectionStoryView.getDocumentSectionClone());
	}

	public void setDocumentSectionNotes(FseDocumentSectionNotesView aDocumentSectionNotesView) {
		this.documentSections.put(FseDocumentSectionType.NOTES, aDocumentSectionNotesView.getDocumentSectionClone());
	}
	
	public void setDocumentMarginLeft(int aDocumentMarginLeft) {
		this.documentMarginLeft = aDocumentMarginLeft;
	}
	
	////  START Audit Block  Wrapper ////
	
	@Override
	public NodeFragAuditBlock getAuditBlock() {
		return getDocumentSectionAudit().getAuditBlock();
	}

	@Override
	public void setAuditBlock(NodeFragAuditBlock anAuditBlock) {
		getDocumentSectionAudit().setAuditBlock(anAuditBlock);
	}
	
	//  Created  //
	
	@Override
	public NodeId getCreatedBy() {
		return getAuditBlock().getCreatedBy();
	}
	
	@Override
	public String getCreatedByNodeIdString() {
		return getAuditBlock().getCreatedBy().getNodeIdString();
	}

	@Override
	public void setCreatedBy(NodeId aNodeId) {
		getAuditBlock().setCreatedBy(aNodeId);
	}
	
	@Override
	public void setCreatedBy(String aNodeIdString) {
		getAuditBlock().setCreatedBy(aNodeIdString);
	}

	@Override
	public Date getCreatedTimestamp() {
		return getAuditBlock().getCreatedTimestamp();
	}
	
	@Override
	public void setCreatedTimestamp(Date aCreatedTimestamp) {
		getAuditBlock().setCreatedTimestamp(aCreatedTimestamp);
	}
	
	//  Updated  //

	@Override
	public NodeId getLastUpdatedBy() {
		return getAuditBlock().getLastUpdatedBy();
	}

	@Override
	public String getLastUpdatedByNodeIdString() {
		return getAuditBlock().getLastUpdatedBy().getNodeIdString();
	}

	@Override
	public void setLastUpdatedBy(NodeId aNodeId) {
		getAuditBlock().setLastUpdatedBy(aNodeId);
	}

	@Override
	public void setLastUpdatedBy(String aNodeIdString) {
		getAuditBlock().setLastUpdatedBy(aNodeIdString);
	}

	@Override
	public Date getLastUpdatedTimestamp() {
		return getAuditBlock().getLastUpdatedTimestamp();
	}

	@Override
	public void setLastUpdatedTimestamp(Date aLastUpdate) {
		getAuditBlock().setLastUpdatedTimestamp(aLastUpdate);
	}
	
	//  Locked  //

	@Override
	public NodeId getLockedBy() {
		return getAuditBlock().getLockedBy();
	}

	@Override
	public String getLockedByNodeIdString() {
		return getAuditBlock().getLockedBy().getNodeIdString();
	}

	@Override
	public void setLockedBy(NodeId aNodeId) {
		getAuditBlock().setLockedBy(aNodeId);
	}
	
	@Override
	public void setLockedBy(String aNodeIdString) {
		getAuditBlock().setLockedBy(aNodeIdString);
	}

	@Override
	public Date getLockedTimestamp() {
		return getAuditBlock().getLockedTimestamp();
	}
	
	@Override
	public void setLockedTimestamp(Date aLockedTimestamp) {
		getAuditBlock().setLockedTimestamp(aLockedTimestamp);
	}

	@Override
	public void lock() {
		getAuditBlock().setLockedBy(FlywheelCommunityAuthentication.getInstance().getFcaUserCredentials().getFcaUserId());
		getAuditBlock().setLockedTimestamp(new Date());
		getAuditBlock().setLocked(true);
	}

	@Override
	public void unlock() {
		// we want to know who unlocked it, and when
		getAuditBlock().setLockedBy(FlywheelCommunityAuthentication.getInstance().getFcaUserCredentials().getFcaUserId());
		getAuditBlock().setLockedTimestamp(new Date());
		getAuditBlock().setLocked(false);
	}
	
	@Override
	public void setLocked(boolean isLocked) {
		getAuditBlock().setLocked(isLocked);
	}

	@Override
	public boolean isLocked() {
		return getAuditBlock().isLocked();
	}
	
	@Override
	public FmmLockStatus getLockStatus() {
		return getAuditBlock().getLockStatus();
	}

	public String getSerializedForComparison() {
		// TODO Auto-generated method stub
		return null;
	}

	public void setDbTimestamp(Date aDbTimestamp) {
		this.dbTimestamp = aDbTimestamp;
	}
	
	////  END Audit Block Wrapper ////

}
